#ifndef OHOS_MATRIX_H_
#define OHOS_MATRIX_H_
#include <array>
#include <cmath>
#include <algorithm>
#include "rect_f.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

namespace webrtc {

class Matrix {
private:
  std::array<float, 9> values;
  static Matrix CreateScale(float sx, float sy);
  static Matrix CreateRotate(float degrees);
  static Matrix CreateTranslate(float dx, float dy);

public:
  static constexpr int MSCALE_X = 0;
  static constexpr int MSKEW_X  = 1;
  static constexpr int MTRANS_X = 2;
  static constexpr int MSKEW_Y  = 3;
  static constexpr int MSCALE_Y = 4;
  static constexpr int MTRANS_Y = 5;
  static constexpr int MPERSP_0 = 6;
  static constexpr int MPERSP_1 = 7;
  static constexpr int MPERSP_2 = 8;

  Matrix();
  static std::array<float, 9> Multiply(const std::array<float, 9>& lhs, const std::array<float, 9>& rhs);

  void Reset();
  void Set(int index, float value);
  float Get(int index);
  void GetValues(std::array<float, 9>& outValues) const;
  void SetValues(const std::array<float, 9>& inValues);
  void PreTranslate(float dx, float dy);
  void PreScale(float sx, float sy);
  void PreScale(float sx, float sy, float px, float py);
  void PreRotate(float degrees);
  void PreConcat(const Matrix& other);
  void PostTranslate(float dx, float dy);
  void PostScale(float sx, float sy);
  void PostScale(float sx, float sy, float px, float py);
  void PostRotate(float degrees);
  void PostConcat(const Matrix& other);
  void MapPoints(float dst[], const float src[], int point_count) const;
  void MapRect(RectF &dst, const RectF &src) const;
  bool IsIdentity() const;
  bool Invert(Matrix& inverse) const;
  void inverseMatrixPoint(float dst[], const float src[]);
};

}

#endif //OHOS_MATRIX_H_
